package com.douyu.ocean.confLoader;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.json.JSONException;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.douyu.ocean.messageSender.MessageSender;
import com.douyu.ocean.serversCheck.CheckHBaseRegion;
import com.douyu.ocean.serversCheck.CheckMySqlRecord;
import com.douyu.ocean.serversCheck.CheckRedisQueue;
import com.douyu.ocean.serversCheck.ServerCheck;

public class JobLoad {

	private static Logger log = LoggerFactory.getLogger(JobLoad.class);
	private Map<String,Integer> sentry_interval = new HashMap<String, Integer>();
	private Map<String,Integer> is_sended = new HashMap<String, Integer>();
	
	public static void main(String[] args) throws JSONException, InterruptedException {
		JobLoad tmp = new JobLoad();
		while(true){
			tmp.getCheck();
			Thread.sleep(120000);
		}
	}
	
	public Map<String,ServerCheck> getJobs() throws JSONException{
		Calendar cd = Calendar.getInstance();
		Map<String,ServerCheck> jobMap = new HashMap<String,ServerCheck>();
		ConnectMysql getConn = new ConnectMysql();
		List<Map<String,String>> jobs = getConn.getJobs();
		if(jobs.size() == 0 || jobs == null){
			log.error("there is no job selected");
			return null;
		}
		JSONObject json = null;
		
		for(Map<String, String> item : jobs){
			int startTime = Integer.parseInt(item.get("start_time"));
			int endTime = Integer.parseInt(item.get("end_time"));
			int nowTime = cd.get(Calendar.HOUR_OF_DAY);
			int interval = Integer.parseInt(item.get("job_interval"));
			String func = item.get("job_type");
			json = new JSONObject(item.get("job_conf"));
			String id = json.getString("id");
			
			if((nowTime >= startTime && nowTime <=endTime) || (startTime == 0 && endTime == 0)){
				log.info("time is suitable at : " + id);
				
				if(!sentry_interval.containsKey(id) || sentry_interval.get(id) == interval){
					sentry_interval.put(id, 1);

					if(func.equals("redis")){
						JSONObject tmp = json.getJSONObject("queues");
						String host = json.getString("host");
						int port = json.getInt("port");
						Map<String,Integer> queues = new HashMap<String, Integer>();
						
						@SuppressWarnings("unchecked")
						Iterator<String> it = tmp.keys();
						while(it.hasNext()){
							String key = (String)it.next();
							int value = Integer.parseInt(tmp.getString(key));
							queues.put(key, value);
						}
						jobMap.put(id,new CheckRedisQueue(host,port,queues));
						
					}else if(func.equals("region")){
						String host = json.getString("host");
						jobMap.put(id,new CheckHBaseRegion(host));
						
					}else if(func.equals("mysql_java")){

						Map<String,String> confs = new HashMap<String,String>();
						@SuppressWarnings("unchecked")
						Iterator<String> it = json.keys();
						while(it.hasNext()){
							String key = (String)it.next();
							String value = json.getString(key);
							confs.put(key, value);
						}
						jobMap.put(id,new CheckMySqlRecord(confs));
					}
					
					log.info("add job '"+ id +"' to job Map");
					
				}else if(interval > sentry_interval.get(id)){
					sentry_interval.put(id, sentry_interval.get(id) + 1);
				}else if(interval < sentry_interval.get(id)){
					log.warn("some thing wrong with checking interval, with id :"+ id +" value : "+ sentry_interval.get(id));
					sentry_interval.put(id, 1);
				}
			}

		}
		return jobMap;
	}	
	
	public void getCheck() throws JSONException{
		Map<String,ServerCheck> jobs = getJobs();
		
		if(jobs == null){
			log.error("error when getting jobs");
			return;
		}

		MessageSender sender = new MessageSender();
		for(Iterator<String> tmp = jobs.keySet().iterator(); tmp.hasNext();){
			String id = tmp.next();
			String func = id.substring(0, id.indexOf("_"));
			String message = jobs.get(id).checkHealth();
			
			if(is_sended.containsKey(id)){
				if(!message.isEmpty()){
					if(is_sended.get(id) == 0){
						log.warn("send message : '"+message+"'");					
					
						if(!func.equals("mysql")){
							is_sended.put(id,1);
						}
						boolean res = sender.sendMessage(func, message);
						if(res){
							log.warn("sended message succeed");
						}else{
							log.error("error when sending message");
						}
					}else if(func.equals("redis")){
						int level = Integer.parseInt(message.substring(message.indexOf("&")+1));
						if(level > is_sended.get(id)){
							is_sended.put(id, level);
							boolean res = sender.sendMessage(func, message);
							if(res){
								log.warn("sended redis message succeed with level :"+level);
							}else{
								log.error("error when sending message");
							}
						}
					}
				}else if(message.isEmpty() && is_sended.get(id) >= 1){
					log.warn("server : "+ id +" come back to health");
					is_sended.put(id,0);
				}
			}else{
				is_sended.put(id, 0);
			}
			
			boolean checked = false;
			for(Map.Entry<String, Integer> entry : is_sended.entrySet()){
				if(entry.getValue() >= 1){
					log.warn("some wrong at "+entry.getKey());
					checked = true;
				}
			}
			if(checked == false)
				log.info("checked with "+ id);
		}
		
	}
}
